package cn.com.utt.unms.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import cn.com.utt.common.log.doLog;
import cn.com.utt.common.util.LocaleMessageSourceUtil;
import cn.com.utt.common.util.Tips;
import cn.com.utt.common.util.UttTool;
import cn.com.utt.common.vo.RestResult;
import cn.com.utt.common.vo.TableInput;
import cn.com.utt.common.vo.TableOutput;
import cn.com.utt.common.vo.User;
import cn.com.utt.unms.mapper.WirelessMapper;
import cn.com.utt.unms.mapper.WirelessNetworkMapper;
import cn.com.utt.unms.mapper.DeviceMapper;
import cn.com.utt.unms.mapper.SsidMapper;
import cn.com.utt.unms.pojo.Wireless;
import cn.com.utt.unms.pojo.Device;
import cn.com.utt.unms.pojo.Ssid;
import cn.com.utt.unms.service.DeviceService;
import cn.com.utt.unms.service.WirelessService;
import cn.com.utt.unms.vo.WirelessInfo;
import cn.com.utt.unms.vo.WirelessInfoInput;

@Service("wirelessService")
public class WirelessServiceImpl implements WirelessService {
	
	@Autowired
    private LocaleMessageSourceUtil messageSourceUtil;

	@Autowired
	private WirelessMapper wirelessMapper;

	@Autowired
	private SsidMapper ssidMapper;

	@Autowired
	private DeviceMapper deviceMapper;

	@Autowired
	private WirelessNetworkMapper wirelessNetworkMapper;

	@Autowired
	private DeviceService deviceService;
	
	@Override
	public TableOutput<WirelessInfo> queryByCondition(TableInput input, long userId) {
		Map<String, Object> conditions = new HashMap<>();
		conditions.put("userId", userId);
		conditions.put("searchs", input.getSearch());
		if (input.getOrder() != null) {
			conditions.put("orderColumn", input.getOrder().getColumn());
			conditions.put("orderDirection", input.getOrder().getDir());
		}
		conditions.put("start", input.getStart());
		conditions.put("rows", input.getRows());
		
		int total = 0;
		List<Wireless> wirelesses = new ArrayList<Wireless>();
		total = wirelessMapper.countByCondition(conditions);
		wirelesses = wirelessMapper.queryByCondition(conditions);
		System.out.println("total:" + total); 
		
		List<WirelessInfo> wirelessInfos = new ArrayList<WirelessInfo>();
		for (Wireless wireless : wirelesses) {
			long wirelessId = wireless.getId();
			Ssid ssid = ssidMapper.querySsidsByWireless(wirelessId);
			WirelessInfo wirelessInfo = new WirelessInfo();
			wirelessInfo.convert(wireless, ssid);
			wirelessInfos.add(wirelessInfo);
		}
		TableOutput<WirelessInfo> output = new TableOutput<>();
		output.setTotal(total);
		output.setRows(input.getRows());
		output.setStart(input.getStart());
		output.setList(wirelessInfos);
		return output;
	}

	@Override
	public List<Wireless> queryWirelessesByNetwork(long networkId) {
		List<Long> networkIds = new ArrayList<>();
		networkIds.add(networkId);
		List<Wireless> wirelesses = wirelessMapper.queryByNetworkIds(networkIds);
		return wirelesses;
	}

	@Override
	public List<Wireless> queryByUser(long userId) {
		List<Wireless> wirelesses = wirelessMapper.queryByUserId(userId);
		return wirelesses;
	}

	public RestResult saveOrUpdate(Wireless wireless, long userId) {
		RestResult result = new RestResult();
		String msg = checkWireless(userId, wireless);
		if (msg == "") {
			Long wirelessId = wireless.getId();
			if (wirelessId == null) {
				wireless.setUserId(userId);
				wirelessMapper.save(wireless);
			} else {
				Wireless or = wirelessMapper.findById(wirelessId);
				if (or == null) {
					result.setErrorCode(1);
					result.setErrorMsg(messageSourceUtil.getMessage(Tips.InvalidParameter));
					return result;
				} else {
					or.setName(wireless.getName());
					wirelessMapper.update(or);
				}
			}
			result.put("wirelessId", wireless.getId());
		} else {
			result.setErrorCode(1);
			result.setErrorMsg(msg);
		}
		return result;
	}

	@SuppressWarnings("serial")
	public RestResult saveOrUpdate(Ssid ssid) {
		RestResult result = new RestResult();
		String msg = checkSsid(ssid);
		if (msg == "") {
			long id = ssid.getId();
			if (id == 0) {
				ssidMapper.save(ssid);
			} else {
				Ssid or = ssidMapper.findById(id);
				if (or == null) {
					result.setErrorCode(1);
					result.setErrorMsg(messageSourceUtil.getMessage(Tips.InvalidParameter));
					return result;
				} else {
					List<Long> networkIds = wirelessNetworkMapper.queryNetworkIdsByWirelessIds(new ArrayList<Long>() {
						{
							add(ssid.getWirelessId());
						}
					});
					if (or.getVid() != ssid.getVid()) {
						for (long networkId : networkIds) {
							List<Long> wirelessIds = wirelessNetworkMapper
									.queryWirelessIdsByNetworkIds(new ArrayList<Long>() {
										{
											add(networkId);
										}
									});
							List<Map<String, Object>> vids = ssidMapper.checkVid(wirelessIds);
							if (vids != null) {
								for (int i = 0; i < vids.size(); i++) {
									Map<String, Object> vid = vids.get(i);
									if (vid.get("vid").toString().equals("0")) {
										continue;
									} else {
										int total = Integer.parseInt(vid.get("total").toString());
										if (vid.get("vid").toString().equals(String.valueOf(ssid.getVid()))) {
											total = total + 1;
										}
										if (total > 1) {
											result.setErrorCode(1);
											result.setErrorMsg(messageSourceUtil.getMessage(Tips.NoSaveVlan));
											return result;
										}
									}
								}
							}
						}
					}
					ssidMapper.update(ssid);
					if (networkIds != null) {
						for (Long networkId : networkIds) {
							List<Device> devices = deviceMapper.queryDevicesByNetworkIds(new ArrayList<Long>() {
								{
									add(networkId);
								}
							});
							List<Wireless> wirelesses = wirelessMapper.queryByNetworkIds(new ArrayList<Long>() {
								{
									add(networkId);
								}
							});
							deviceService.updateDeviceWireless(devices, wirelesses);
						}
					}
				}
			}
			result.setErrorMsg(messageSourceUtil.getMessage(Tips.OperationSucceed));
		} else {
			result.setErrorCode(1);
			result.setErrorMsg(msg);
		}
		return result;
	}

	@Override
	public boolean hasRights(List<Wireless> wirelesses, long userId) {
		for (Wireless wireless : wirelesses) {
			if (wireless.getUserId() != userId) {
				return false;
			}
		}
		return true;
	}

	@Override
	public boolean hasRight(Wireless wireless, long userId) {
		if (wireless.getUserId() != userId) {
			return true;
		}
		return false;
	}

	@Override
	@Transactional
	@doLog(description = Tips.LogDeleteWireless, key = { "" })
	public RestResult delete(List<Long> wirelessIds, long userId) {
		RestResult result = new RestResult();
		if (wirelessIds != null && wirelessIds.size() > 0) {
			List<Wireless> wirelesses = wirelessMapper.queryByIds(wirelessIds);
			if (!hasRights(wirelesses, userId)) {
				result.setErrorCode(2);
				result.setErrorMsg(messageSourceUtil.getMessage(Tips.NetworkNoDelete2));
				return result;
			}
			if (wirelesses == null || wirelesses.size() == 0) {
				result.setErrorCode(2);
				result.setErrorMsg(messageSourceUtil.getMessage(Tips.InvalidParameter));
				return result;
			}
			List<Long> ids = wirelessNetworkMapper.queryNetworkIdsByWirelessIds(wirelessIds);
			if (ids != null && ids.size() > 0) {
				if (deviceMapper.queryDevicesByNetworkIds(ids).size() > 0) {
					result.setErrorCode(2);
					result.setErrorMsg(messageSourceUtil.getMessage(Tips.NetworkNoDelete1));
					return result;
				}
			}
			wirelessMapper.delete(wirelessIds);
			ssidMapper.deleteSsidByWirelesses(wirelessIds);
		} else {
			result.setErrorCode(1);
			result.setErrorMsg(messageSourceUtil.getMessage(Tips.InvalidParameter));
			return result;
		}
		result.setErrorMsg(messageSourceUtil.getMessage(Tips.OperationSucceed));
		return result;
	}

	private String checkWireless(long userId, Wireless wireless) {
		String errorMsg = "";
		if (wireless != null) {
			Long wirelessId = wireless.getId();
			//修改其他账号的无线配置 提示没有权限
			if(wirelessId != null && wirelessId >= 0){
				Wireless w = wirelessMapper.findById(wirelessId);
				if(w.getUserId() != userId){
					errorMsg = messageSourceUtil.getMessage(Tips.NetworkNoDelete2);
					return errorMsg;
				}
			}
			String name = wireless.getName();
			if (name == null || name.equals("")) {
				errorMsg = messageSourceUtil.getMessage(Tips.WirelessIsNotNull);
				return errorMsg;
			}
			if (name.length() > 64) {
				errorMsg = messageSourceUtil.getMessage(Tips.WirelessNameNotGreaterThan64Letters);
				return errorMsg;
			}
		} else {
			errorMsg = messageSourceUtil.getMessage(Tips.InvalidParameter);
		}
		return errorMsg;
	}

	private String checkSsid(Ssid ssid) {
		String errorMsg = "";
		if (ssid != null) {
			long id = ssid.getId();
			if (id < 0) {
				id = (long) 0;
				ssid.setId(id);
			}

			long wirelessId = ssid.getWirelessId();
			if (wirelessId <= 0) {
				errorMsg = messageSourceUtil.getMessage(Tips.InvalidParameter);
			}
			Wireless wireless = wirelessMapper.findById(wirelessId);
			if (wireless == null) {
				errorMsg = messageSourceUtil.getMessage(Tips.InvalidParameter);
			}
			String name = ssid.getName();
			if (name == null || name.equals("")) {
				errorMsg = messageSourceUtil.getMessage(Tips.SsidIsNotNull);
			}
			if (name.length() > 32) {
				errorMsg = messageSourceUtil.getMessage(Tips.SsidNameNotGreaterThan32Letters);
			}
			if (UttTool.isSsidSafe(name) == false) {
				errorMsg = messageSourceUtil.getMessage(Tips.SsidNameNoContainsSpace).replaceAll("#", UttTool.SSID_UNSAFE_STR);
			}
		} else {
			errorMsg = messageSourceUtil.getMessage(Tips.InvalidParameter);
		}
		return errorMsg;
	}

	@Override
	@doLog(description = Tips.LogWirelessAddOrUpdate, key = { "#config.wireless.name" })
	public RestResult saveOrUpdate(WirelessInfoInput config, User user) {
		RestResult result = new RestResult();
		result = saveOrUpdate(config.getWireless(), user.getParentId() == null?user.getId():user.getParentId());
		if (result.getErrorCode() == 0) {
			Ssid ssid = config.getSsid();
			long wirelessId = Long.parseLong(result.toJsonObject().get("wirelessId").toString());
			ssid.setWirelessId(wirelessId);
			result = saveOrUpdate(ssid);
			if (result.getErrorCode() != 0) {
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			}
		}
		return result;
	}

}
